#pragma once

//#include "errordefine.h"

#ifndef IN
#define IN
#endif

#ifndef OUT
#define OUT
#endif

#ifndef INOUT
#define INOUT
#endif

#ifndef NULL
#define NULL 0
#endif

#ifdef _WIN32
// 放在class关键字后面，以及函数或者变量定义的前面
#define DH_PROXY_DEPRECATED	__declspec(deprecated)
#else
#define DH_PROXY_DEPRECATED	__attribute__ ((deprecated))
#endif // #ifdef WIN32

#include <vector>
#include <map>
#include <list>
#include <iostream>
#include <memory>
#include <functional>

#ifdef _WIN32
#include <windows.h>

#ifdef DH_PROXY_EXPORTS
#define DH_PROXY_API extern "C" __declspec(dllexport)
#else
#define DH_PROXY_API extern "C" __declspec(dllimport)
#endif

#define DHPROXY_CALLTYPE				__stdcall
#define DHPROXY_CALL_METHOD			__stdcall  //__cdecl

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0502
#endif

#ifndef __int8_t_defined
#define __int8_t_defined
typedef signed char			int8_t;
typedef unsigned char		uint8_t;
typedef short int			int16_t;
typedef unsigned short int	uint16_t;
typedef int					int32_t;
typedef unsigned int		uint32_t;
typedef __int64				int64_t;
typedef unsigned __int64	uint64_t;
#endif
#else//fixme: delete these defs
//	#include <stdio.h>
#include <string.h> // memset()
#include <stddef.h> // NULL
#include <stdint.h> // int8_t
//	#include <errno.h>

#define DH_PROXY_API extern "C"
#define DHPROXY_CALLTYPE
#define DHPROXY_CALL_METHOD

#define WORD		unsigned short
#define DWORD		unsigned int
#define LONG		int
#define LONGINT		long int
#define DWORDINT	long int
#define LPDWORD		DWORD*
#define BOOL		int
#define TRUE		1
#define FALSE		0
#define BYTE		unsigned char
#define UINT		unsigned int
#define HDC			void*
#define HWND		void*
#define LPVOID		void*
//	#define NULL		0
#define LLONG		long
#define INT64		long long
#define LDWORD		long

#define CALLBACK

#ifndef MAX_PATH
#define MAX_PATH	260
#endif
#endif

using namespace std;

#define PROXY_MAX_STRINGNUM    8

/// 云台最大速度
#define _PTZ_MAX_SPEED	15

typedef enum
{
    _PTZ_PANRIGHT = 0,	        ///< 云台右转
    _PTZ_RIGHTUP = 1,	            ///< 云台上仰和右转
    _PTZ_TILTUP = 2,                	///< 云台上仰
    _PTZ_LEFTUP = 3,	            ///< 云台上仰和左转
    _PTZ_PANLEFT = 4,	            ///< 云台左转
    _PTZ_LEFTDOWN = 5,	        ///< 云台下俯和左转
    _PTZ_TILTDOWN = 6,	        ///< 云台下俯
    _PTZ_RIGHTDOWN = 7,	    ///< 云台下俯和右转
    _PTZ_SCAN = 8,	                ///< 云台左右自动扫描
    _PTZ_HALT = 9,	                ///< 云台停止
    _PTZ_IRIS = 10,	                ///< 光圈变化(param>0扩大、param<0缩小、param=0表示停止)
    _PTZ_ZOOM_IN = 11,	        ///< 焦距变大(param>0倍率变大、param<0倍率变小、param=0表示停止)
    _PTZ_FOCUS = 12,	            ///< 聚焦调整(param>0前调、param<0后调、param=0表示停止)
    _PTZ_VIEW = 13,	                ///< 转到指定预置位
    _PTZ_SETVIEW = 14,	        ///< 设置当前位置为一个预置位
    _PTZ_AUX = 15,	                ///< 接通辅助设备开关(param=1 表示开,param=0 表示关,其它值无效)
    _PTZ_WASH = 16,	            ///< 清洗
    _PTZ_WIPE = 17,	                ///< 接通雨刷开关
    _PTZ_LIGHT = 18,	            ///< 接通灯光电源
    _PTZ_POWER = 19,	            ///< 电源
    _PTZ_CLRVIEW=20					///清除预置位
} _PTZ_Command;

struct _proxy_osd_info
{
    uint32_t iShowString;						 // 预览的图象上是否显示字符,0-不显示,1-显示 整个预览画面大小704*576,单个字符的大小为32*32
    uint32_t iStringSize;							 /* 该行字符的长度，不能大于44个字符 */
    uint32_t iShowStringTopLeftX;        /* 字符显示位置的x坐标 */
    uint32_t iShowStringTopLeftY;        /* 字符名称显示位置的y坐标 */
    char sString[44];								/* 要显示的字符内容 */
};
struct _proxy_showstring_info
{
    uint32_t dwSize;
    _proxy_osd_info struStringInfo[PROXY_MAX_STRINGNUM];                /* 要显示的字符内容 */
};


struct _dau_device_info
{
    char  _dev_name[64];
    char _dev_serialnum[64];
    uint32_t _dev_version;
    uint32_t _dev_type;
};

struct _channel_infos
{
    int channel_index;
    char _channel_name[64];
    int  _chn_status;
    int  _dev_type;
    int _access_portocol;
    char _ipaddr[64];
    int   _port;
    int _off_reason;
    int _remote_index;
    char _manufacture[64];
    char _dev_model[64];
    char _gb_id[32];
};
struct _device_channel_info
{
    int _channel_num;
    _channel_infos   _chn_info[256];
};
enum _proxy_dev_type
{
    hikvision_dev = 1,
    uniview_dev = 2,
    dahua_dev = 3,
    hikisapi_dev=4,
    dahua_isapi_dev = 5,
    onvif_dev=6,
    uniview_sdk=7,
    dahua_sdk=8
};
struct _proxy_dev_info
{
    int				devicetype;  //设备类型
    string			ipaddr;
    int				port;
    string			username;
    string			password;
    int				link_mode;
};

struct _setup_alarm_info
{
    uint32_t dwSize;
    uint8_t  byLevel; //布防优先级，0-一等级（高），1-二等级（中），2-三等级（低）
    uint8_t  byAlarmInfoType; //上传报警信息类型（抓拍机支持），0-老报警信息（NET_DVR_PLATE_RESULT），1-新报警信息(NET_ITS_PLATE_RESULT)2012-9-28
    uint8_t  byRetAlarmTypeV40; //0--返回NET_DVR_ALARMINFO_V30或NET_DVR_ALARMINFO, 1--设备支持NET_DVR_ALARMINFO_V40则返回NET_DVR_ALARMINFO_V40，不支持则返回NET_DVR_ALARMINFO_V30或NET_DVR_ALARMINFO
    uint8_t  byRetDevInfoVersion; //CVR上传报警信息回调结构体版本号 0-COMM_ALARM_DEVICE， 1-COMM_ALARM_DEVICE_V40
    uint8_t  byRetVQDAlarmType; //VQD报警上传类型，0-上传报报警NET_DVR_VQD_DIAGNOSE_INFO，1-上传报警NET_DVR_VQD_ALARM
    //1-表示人脸侦测报警扩展(INTER_FACE_DETECTION),0-表示原先支持结构(INTER_FACESNAP_RESULT)
    uint8_t  byFaceAlarmDetection;
    //Bit0- 表示二级布防是否上传图片: 0-上传，1-不上传
    //Bit1- 表示开启数据上传确认机制；0-不开启，1-开启
    //Bit6- 表示雷达检测报警(eventType:radarDetection)是否开启实时上传；0-不开启，1-开启（用于web插件实时显示雷达目标轨迹）
    uint8_t  bySupport;
    //断网续传类型
    //bit0-车牌检测（IPC） （0-不续传，1-续传）
    //bit1-客流统计（IPC）  （0-不续传，1-续传）
    //bit2-热度图统计（IPC） （0-不续传，1-续传）
    //bit3-人脸抓拍（IPC） （0-不续传，1-续传）
    //bit4-人脸对比（IPC） （0-不续传，1-续传）
    //bit5-JSON报警透传（IPC） （0-不续传，1-续传）
    //bit6-热度图按人员停留时间统计数据上传事件（0-不续传，1-续传）
    //bit7-热度图按人数统计数据上传事件的确认机制（0-不续传，1-续传）
    uint8_t  byBrokenNetHttp;
    uint16_t  wTaskNo;    //任务处理号 和 (上传数据NET_DVR_VEHICLE_RECOG_RESULT中的字段dwTaskNo对应 同时 下发任务结构 NET_DVR_VEHICLE_RECOG_COND中的字段dwTaskNo对应)
    uint8_t  byDeployType;    //布防类型：0-客户端布防，1-实时布防
    uint8_t  bySubScription;	//订阅，按位表示，未开启订阅不上报  //占位Bit7-移动侦测人车分类是否传图；0-不传图(V30上报)，1-传图(V40上报)
    //断网续传响应类型V60版本
    //bit0-AID事件(COMM_ALARM_AID_V41) （0-不续传，1-续传）
    //bit1-TFS事件（COMM_ALARM_TFS）  （0-不续传，1-续传）
    //bit2-TPS统计过车事件（COMM_ALARM_TPS_STATISTICS）  （0-不续传，1-续传）
    uint8_t  byBrokenNetHttpV60;
    uint8_t  byRes1;
    uint8_t  byAlarmTypeURL;//bit0-表示人脸抓拍报警上传（INTER_FACESNAP_RESULT）；0-表示二进制传输，1-表示URL传输（设备支持的情况下，设备支持能力根据具体报警能力集判断,同时设备需要支持URL的相关服务，当前是”云存储“）
    //bit1-表示EVENT_JSON中图片数据长传类型；0-表示二进制传输，1-表示URL传输（设备支持的情况下，设备支持能力根据具体报警能力集判断）
    //bit2 - 人脸比对(报警类型为COMM_SNAP_MATCH_ALARM)中图片数据上传类型：0 - 二进制传输，1 - URL传输
    //bit3 - 行为分析(报警类型为COMM_ALARM_RULE)中图片数据上传类型：0 - 二进制传输，1 - URL传输，本字段设备是否支持，对应软硬件能力集中<isSupportBehaviorUploadByCloudStorageURL>节点是否返回且为true
    uint8_t  byCustomCtrl;//Bit0- 表示支持副驾驶人脸子图上传: 0-不上传,1-上传
    uint8_t  byRes4[128];
};


enum _alarm_vca_event_type
{
    PROXY_VCA_EVENT_TRAVERSE_PLANE=0x01,//穿越警戒面
    PROXY_VCA_ENTER_AREA = 0x2,        //目标进入区域,支持区域规则
    PROXY_VCA_EXIT_AREA = 0x4,        //目标离开区域,支持区域规则
    PROXY_VCA_INTRUSION = 0x8,        //周界入侵,支持区域规则
    PROXY_VCA_LOITER = 0x10,       //徘徊,支持区域规则
    PROXY_VCA_LEFT_TAKE = 0x20,       //物品遗留拿取,支持区域规则
    PROXY_VCA_PARKING = 0x40,       //停车,支持区域规则
    PROXY_VCA_RUN = 0x80,       //快速移动,支持区域规则
    PROXY_VCA_HIGH_DENSITY = 0x100,      //区域内人员聚集,支持区域规则
    PROXY_VCA_VIOLENT_MOTION = 0x200,         //剧烈运动检测
    PROXY_VCA_REACH_HIGHT = 0x400,         //攀高检测
    PROXY_VCA_GET_UP = 0x800,         //起身检测
    PROXY_VCA_LEFT = 0x1000,     //物品遗留
    PROXY_VCA_TAKE = 0x2000,     //物品拿取
    PROXY_VCA_LEAVE_POSITION = 0x4000,     //离岗
    PROXY_VCA_TRAIL = 0x8000,     //尾随
    PROXY_VCA_KEY_PERSON_GET_UP = 0x10000,    //重点人员起身检测
    PROXY_VCA_STANDUP = 0x20000,    //起立
    PROXY_VCA_FALL_DOWN = 0x80000,    //倒地检测
    PROXY_VCA_AUDIO_ABNORMAL = 0x100000,   //声强突变检测
    PROXY_VCA_ADV_REACH_HEIGHT = 0x200000,   //折线攀高
    PROXY_VCA_TOILET_TARRY = 0x400000,   //如厕超时
    PROXY_VCA_YARD_TARRY = 0x800000,   //放风场滞留
    PROXY_VCA_ADV_TRAVERSE_PLANE = 0x1000000,  //折线警戒面
    PROXY_VCA_LECTURE = 0x2000000,  //授课
    PROXY_VCA_ANSWER = 0x4000000,  //回答问题
    PROXY_VCA_HUMAN_ENTER = 0x10000000, //人靠近ATM           只在ATM_PANEL模式下支持
    PROXY_VCA_OVER_TIME = 0x20000000, //操作超时            只在ATM_PANEL模式下支持
    PROXY_VCA_STICK_UP = 0x40000000, //贴纸条,支持区域规则
    PROXY_VCA_INSTALL_SCANNER = 0x80000000  //安装读卡器,支持区域规则
};

struct _proxy_alarm_rect {
    float   fX;
    float   fY;
    float   fWidth;
    float   fHeight;
};

enum _proxy_alarm_cmd
{
    _alarm_rule=0x1000,
    _vca_alarm = 0x1001,
    _fire_detection=0x1002,
    _fire_alarm=0x1003,
    _hik_isapi_alarm=0x1004,
    _plate_upload = 0x1005,
    _face_snap = 0x1006,
    _comm_alarm=0x1007

};
enum _proxy_firedetection_type
{
    //报警子类型：0 - 火点检测报警，1 - 烟雾检测报警，2 - 烟火报警
};


//_alarm_rule
struct _proxy_vca_base_info
{
    uint32_t _type;
    _proxy_alarm_rect _rect;
    string  _image;
    uint32_t _image_len;
};
//_vca_alarm
struct _proxy_vca_alarm_info
{
    char* _json_value;
    uint32_t datalen;
};

struct _proxy_sadp_device_info
{
    string  _serial_no;
    string  _dev_mac;
    string  _dev_ipaddr;
    string  _dev_netmask;
    string _dev_gateway;
    string  _dev_type;
    int	   _dev_port;
    string  _dev_softver;
    string  _dev_devdesc;
    string  _dev_oeminfo;
    string _user_name;
};

struct _record_info
{
    string  _filename;
    int   _record_type;
    uint64_t  _begintime; //录像文件开始时间，UTC时间格式，单位秒
    uint64_t  _endtime; //录像文件开始时间，UTC时间格式，单位秒
    uint64_t _file_size; //录像文件大小
};

struct _record_list_info
{
    int _record_nums;
    list< _record_info>  _record_infos;
};

struct _ptz_preset_info
{
    int _preset_id;
    string _preset_name;
};

struct _ptz_preset_list_info
{
    int _preset_num;
    list<_ptz_preset_info> _preset_infos;
};

typedef enum
{
    _FILL_PRES_SEQ = 30,/* 将预置点加入巡航序列 */
    _SET_SEQ_DWELL = 31,/* 设置巡航点停顿时间 */
    _SET_SEQ_SPEED=32,    /* 设置巡航速度 */
    _CLE_PRE_SEQ=33,    /* 将预置点从巡航序列中删除 */
    _RUN_SEQ=      37 ,   /* 开始巡航 */
    _STOP_SEQ=  38    /* 停止巡航 */
}_CURISE_COMMAND;

//alarm callback
typedef void (CALLBACK* Proxy_MessageCallback)(uint32_t lCommand, _proxy_dev_info& devinfo,char* pAlarmInfo, uint32_t dwBufLen, void* pUser);

//_find_time 搜索返回时间,时间单位为秒，如果设置为-1，则搜索时间为10秒返回
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_SdapFindDevice(_proxy_dev_type _dev_type,list<_proxy_sadp_device_info> &_dadp_info,int _find_time);
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_SdapFindDevicePlus(_proxy_dev_type _dev_type, string& _json_str, int _find_time);
//初始化sdk
//设置的路径为绝对路径
DH_PROXY_API   int  DHPROXY_CALL_METHOD Proxy_SetLibraryPath(string _lib_path);
DH_PROXY_API   int  DHPROXY_CALL_METHOD Proxy_InitLibrary();
DH_PROXY_API   int  DHPROXY_CALL_METHOD Proxy_ReleaseLibrary();

//添加设备
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_AddDevicePlus(_proxy_dev_info& devinfo, string dev_uuid);

DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_AddDevice(_proxy_dev_info &devinfo,string & dev_uuid);
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_DeleteDevice(string dev_uuid);
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_GetDeviceInfo(string dev_uuid, _dau_device_info &device_info);
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_GetDevChannelInfo( string dev_uuid, _device_channel_info& channel_info);


DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_Login(string dev_uuid);
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_Logout(string dev_uuid);

//获取登录状态,0代表不在线，1代表在线
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_GetDeviceState(string dev_uuid);

//alarm
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_SetAlarmCallback(string dev_uuid, Proxy_MessageCallback callback_func, void* pUser);
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_SetupAlarmChan( string dev_uuid, _setup_alarm_info*   lpSetupParam,const char* pData,uint32_t  dwDataLen);
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_StopAlarmChan( string dev_uuid);

//stream ???
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_StartStream(string dev_uuid,string channel,string subchannel,string streamurl, string& stream_uuid);
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_StopStream( string dev_uuid, string channel, string subchannel, string stream_uuid);

//获取实时视频的url地址
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_GetLiveStreamUrl(string dev_uuid, string channel, string subchannel,  string& stream_url);
//获取录像视频的rtsp的url地址
// 时间格式为YYYYMMDDhhmmss
//vod_type 告警类型，按位表示，如果为0表示查询时间段内所有告警


DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_GetVodStreamUrl(string dev_uuid, string channel, string subchannel, string begintime, string endtime, uint32_t  vod_type, string& stream_url);

DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_QureyRecordInfos(string dev_uuid, string channel, string subchannel, string begintime, string endtime, uint32_t  vod_type, _record_list_info & _record_list);


DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_MakeKeyFrame(string dev_uuid, string channel, string subchannel);

//osd
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_GetOsdShowString(string dev_uuid,string channel, _proxy_showstring_info &osd_info);
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_SetOsdShowString( string dev_uuid, string channel,_proxy_showstring_info* osd_info);

//ptz
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_PtzControl(string dev_uuid, string channel, int command,int param);
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_GetPresetInfos(string dev_uuid, string channel, _ptz_preset_list_info &preset_infos);
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_SetPresetName(string dev_uuid, string channel, int preset_id, string preset_name);
//command为_CURISE_COMMAND
//cruiseroute：巡航路径，（最多支持32个，从1开始）
//cruiseid：巡航点 （最多支持32个，从1开始）
//param：不同巡航命令时的值不同，预置点(最大300)、时间(最大255)、速度(最大40)
DH_PROXY_API int DHPROXY_CALL_METHOD Proxy_PTZCruiseControl(string dev_uuid, string channel, int command, int cruiseroute, int cruiseid, int param);